package com.un.ebs.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.un.ebs.core.exception.BusinessEntityNotFoundException;
import com.un.ebs.core.exception.BusinessException;
import com.un.ebs.core.util.StringUtils;
import com.un.ebs.product.domain.Product;
import com.un.ebs.product.domain.ProductSaleClass;
import com.un.ebs.product.dto.ProductSaleClassDto;
import com.un.ebs.product.mapper.ProductMapper;
import com.un.ebs.product.mapper.ProductSaleClassMapper;
import com.un.ebs.product.service.ProductSaleClassService;
import com.un.ebs.sys.dto.ObjectParentAndIndexChangeDto;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author liubo
 * @since 2019-09-16
 */
@Service
public class ProductSaleClassServiceImpl extends ServiceImpl<ProductSaleClassMapper, ProductSaleClass> implements ProductSaleClassService {

    @Resource
    private ProductMapper productMapper;

    @Override
    public void update(ProductSaleClassDto req) {
        ProductSaleClass obj;
        if (!StringUtils.isNullOrEmpty(req.getId())) {
            obj = getById(req.getId());
        } else {
            obj = new ProductSaleClass();
            obj.setSort(baseMapper.maxSort());
        }
        obj.setClassName(req.getName());
        obj.setParentId(req.getParentId());
        obj.insertOrUpdate();
    }

    @Override
    public ProductSaleClass queryById(String id) {
        return getBaseMapper().selectById(id);
    }

    @Override
    public void changeParent(String id, String parentId) {
        ProductSaleClass obj = getById(id);
        obj.setParentId(parentId);
        getBaseMapper().updateById(obj);
    }

    @Override
    public List<ProductSaleClass> queryAll() {
        LambdaQueryWrapper<ProductSaleClass> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSaleClass::getIsDelete, false);
        lq.orderByAsc(ProductSaleClass::getSort);
        return baseMapper.selectList(lq);
    }

    @Override
    public void addByProduct(String classId, List<String> productIds) {
        ProductSaleClass smallClass = queryById(classId);
        if (smallClass == null) {
            throw new BusinessException("指定的销售品类没有找到。");
        }
        ProductSaleClass mediumClass = queryById(smallClass.getParentId());
        if (mediumClass == null) {
            throw new BusinessException("当前类别必须有上一级类别，作为商品的中类。");
        }
        ProductSaleClass largeClass = queryById(mediumClass.getParentId());
        if (largeClass == null) {
            throw new BusinessException("当前类别层次异常，没有可作为大类的类别。");
        }

        for (String id : productIds) {
            Product spu = productMapper.selectById(id);
            if(spu==null){
                throw new BusinessEntityNotFoundException(id,"SPU");
            }
            spu.setSaleLargeClassId(largeClass.getId());
            spu.setSaleMediumClassId(mediumClass.getId());
            spu.setSaleSmallClassId(smallClass.getId());
            spu.updateById();
        }
    }

    @Override
    public void removeByProduct(String classId, List<String> productIds) {
        LambdaQueryWrapper<Product> lq = Wrappers.lambdaQuery();
        lq.eq(Product::getSaleSmallClassId,classId);
        lq.in(Product::getId,productIds);
        for(Product spu : productMapper.selectList(lq)){
            spu.setSaleSmallClassId(null);
            spu.setSaleMediumClassId(null);
            spu.setSaleLargeClassId(null);
            spu.updateById();
        }
    }

    @Override
    public boolean saveBatch(Collection<ProductSaleClass> entityList) {
        return false;
    }

    @Transactional
    @Override
    public void changeNode(List<ObjectParentAndIndexChangeDto> nodes) {
        for (ObjectParentAndIndexChangeDto node : nodes) {
            ProductSaleClass productClass = baseMapper.selectById(node.getId());
            productClass.setParentId(node.getParentId());
            productClass.updateById();
        }
    }

    @Override
    public List<ProductSaleClass> queryParent() {
        LambdaQueryWrapper<ProductSaleClass> wrapper = Wrappers.lambdaQuery();
        wrapper.isNull(ProductSaleClass::getParentId);
        wrapper.orderByAsc(ProductSaleClass::getSort);
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public List<ProductSaleClass> queryByParentId(String parentId) {
        LambdaQueryWrapper<ProductSaleClass> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ProductSaleClass::getParentId, parentId);
        wrapper.orderByAsc(ProductSaleClass::getSort);
        return getBaseMapper().selectList(wrapper);
    }

    @Override
    public IPage<ProductSaleClass> queryPageByParentId(String parentId, int pageSize, int pageIndex) {
        Page<ProductSaleClass> page = new Page<>(pageIndex, pageSize);
        LambdaQueryWrapper<ProductSaleClass> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ProductSaleClass::getParentId, parentId);
        wrapper.orderByAsc(ProductSaleClass::getSort);
        return getBaseMapper().selectPage(page, wrapper);
    }

    @Override
    public List<String> queryParentIds(String classId) {
        List<String> result = new ArrayList<>();
        LambdaQueryWrapper<ProductSaleClass> lq = Wrappers.lambdaQuery();
        lq.eq(ProductSaleClass::getId, classId);
        ProductSaleClass obj = baseMapper.selectOne(lq);
        if (obj == null) {
            return null;
        }
        result.add(classId);
        return result;
    }

    @Override
    public void changeSort(String id, int index) {
        ProductSaleClass obj = getById(id);
        obj.setSort(index);
        getBaseMapper().updateById(obj);
    }

    @Override
    public void delete(String id) {
        LambdaQueryWrapper<Product> lq = Wrappers.lambdaQuery();
        lq.eq(Product::getClassId, id);
        lq.eq(Product::getIsDelete, false);
        long cnt = productMapper.selectCount(lq);
        if (cnt > 0) {
            throw new BusinessException("当前类别下还有 " + cnt + " 笔商品没有删除，请先删除商品后再执行此操作。");
        }
        getBaseMapper().deleteById(id);
    }

}